package com.network.util;

import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @decription 执行远程shell命令，并获取结果--实现分析日志
 * @author zhangwenchao
 * @date  2018/6/8
 *
 */
public class ShellUtils {


    static Logger logger= LoggerFactory.getLogger(ShellUtils.class);
    /**配置连接
     * @param user
     * @param passwd
     * @param host
     * @param post
     * @throws Exception
     */
    public static Session connect(String user, String passwd, String host, int post) throws Exception {
        JSch jsch = new JSch();
        Session session = jsch.getSession(user, host, post);
        if (session == null) {
            throw new Exception("session is null");
        }
        session.setPassword(passwd);
        java.util.Properties config = new java.util.Properties();
        //第一次登陆
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        try {
            session.connect(30000);
        } catch (Exception e) {
            throw new Exception("连接远程端口无效或用户名密码错误");
        }
        return session;
    }


    /**
     * @description 执行shell命令
     * @param command shell 命令
     * @param user 用户名
     * @param passwd 密码
     * @param host ip地址
     * @throws Exception
     */
    public static void execCmd(String command, String user, String passwd, String host, int port) throws Exception {
        System.out.println(command);
        Session session= connect(user, passwd,host,port);
        BufferedReader reader = null;
        Channel channel = null;
        try {
            channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);
            channel.setInputStream(null);
            ((ChannelExec) channel).setErrStream(System.err);
            channel.connect();
            InputStream in = channel.getInputStream();
            reader = new BufferedReader(new InputStreamReader(in));
            String buf = null;
            //返回数据
            while ((buf = reader.readLine()) != null) {
                System.out.println(buf);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSchException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            channel.disconnect();
            session.disconnect();
        }
    }



    public static List<String> execCmdAndOutput(String command, String user, String passwd, String host, int port) throws Exception {

        Session session= connect(user, passwd,host,port);
        BufferedReader reader = null;
        Channel channel = null;
        try {
            channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);

            channel.setInputStream(null);
            ((ChannelExec) channel).setErrStream(System.err);

            channel.connect();
            InputStream in = channel.getInputStream();
            reader = new BufferedReader(new InputStreamReader(in));
            List<String> output = new ArrayList<String>();
            String buf = null;
            //返回数据
            while ((buf = reader.readLine()) != null) {
                output.add(buf);
            }
            return output;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSchException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            channel.disconnect();
            session.disconnect();
        }
        return null;
    }


    /**
     *
     * @param logPath
     * @param user
     * @param passwd
     * @param host
     * @param port
     * @return
     * @throws Exception
     */
    public static Set<String> execCmdAndgetOlderUserIDs(Set<String> userIDSet, String logPath, List<String> fileNames, String user, String passwd, String host, int port) throws Exception {

        Session session= connect(user, passwd,host,port);
        try {
            for (String fileName : fileNames) {
                String command = "cat "+fileName+"|grep '/login'";
                Channel channel = null;
                BufferedReader reader = null;
                try {
                    channel = session.openChannel("exec");
                    ((ChannelExec) channel).setCommand(command);

                    channel.setInputStream(null);
                    ((ChannelExec) channel).setErrStream(System.err);

                    channel.connect();
                    InputStream in = channel.getInputStream();
                    reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
                    String buf = null;
                    //返回数据
                    while ((buf = reader.readLine()) != null) {
                        analyseLogOneLine(userIDSet, buf);
                    }
                } finally {
                    reader.close();
                    channel.disconnect();
                }

            }
        } finally {
            session.disconnect();
        }
        return userIDSet;
    }


    /**
     * 解析一行日志，获取老用户uid存放到Set中并返回
     * @param str
     * @return
     */
    private static Set<String> analyseLogOneLine(Set<String> userIDSet, String str) {
        String[] logLine  = str.split("\\s+\\|\\s+");
        String userToken = null;
        String cacheResult=null;
        if(logLine!=null && logLine.length==12){
            userToken= logLine[6].trim();
            cacheResult = logLine[10].trim();
        }
        if(CommonUtils.isNotNull(cacheResult)){
            logger.info("*******************"+cacheResult);
        }
        return userIDSet;
    }


    public static void main(String[] args) throws Exception {

        int poolSize = Runtime.getRuntime().availableProcessors() * 2;

        System.out.println(poolSize);

        ExecutorService executorService = new ThreadPoolExecutor(poolSize, poolSize,
                0, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(512), // 使用有界队列，避免OOM
                new ThreadPoolExecutor.DiscardPolicy());



//        for (int i=0;i<10;i++)
//        {
//            Thread t1=new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    try {
//                        execCmd("ls -l","root","123456","192.168.1.193",22);
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                }
//            });
//            executorService.submit(t1);
//
//            Thread.sleep(1000);
//        }



    }

}
